package com.xbh.management.security;

import com.nimbusds.jose.JOSEException;
import com.xbh.common.utils.RedisUtils;
import com.xbh.management.entity.PayloadDTO;
import com.xbh.management.exception.JwtSignatureVerifyException;
import com.xbh.management.model.ManLoginLog;
import com.xbh.management.service.ManLoginLogService;
import com.xbh.management.utils.JwtUtilManagement;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;

/**
 * @program: management-center
 * @description: 自定义退出逻辑
 * @author: 许宝华
 * @create: 2021-10-05 15:09
 */

public class TokenLogoutHandler implements LogoutHandler {

    private static Logger log = LoggerFactory.getLogger(TokenLogoutHandler.class);

    private RedisUtils redisUtils;

    private JwtUtilManagement jwtUtilManagement;


    private ManLoginLogService manLoginLogService;

    public TokenLogoutHandler(RedisUtils redisUtils, JwtUtilManagement jwtUtilManagement, ManLoginLogService manLoginLogService) {
        this.redisUtils = redisUtils;
        this.jwtUtilManagement = jwtUtilManagement;
        this.manLoginLogService = manLoginLogService;
    }

    @SneakyThrows
    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        log.info("注销登录，拦截到了注销登录的请求");
        //1、从header里面获取token
        String token = request.getHeader("Authorization");
        //退出日志
        ManLoginLog manLoginLog = new ManLoginLog();
        manLoginLog.setUsername(JwtUtilManagement.getUsername());
        manLoginLog.setUserId(JwtUtilManagement.getUserId());
        manLoginLog.setLogInfo("注销登录");
        manLoginLog.setNodeColor("red");
        manLoginLog.setLogTitle("退出登录");
        manLoginLog.setCreatePerson(JwtUtilManagement.getUsername());
        manLoginLog.setUpdatePerson(JwtUtilManagement.getUsername());
        manLoginLogService.save(manLoginLog);
        //2、token不为空，移除token，从Redis删除token
        if(token != null){
            try {
                //解析token里的用户信息
                PayloadDTO currentUser = jwtUtilManagement.getJwtPayload();
                log.info("解析后的用户数据为:"+currentUser.toString());
                //将Redis里的用户信息及用户权限删除
                redisUtils.remove(currentUser.getName());
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (JwtSignatureVerifyException e) {
                e.printStackTrace();
            } catch (JOSEException e) {
                e.printStackTrace();
            }
        }
    }
}
